package com.my.test.thread.conditition.old;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MyQueue<T> {

	private Object item[];// 用数组实现一个队列

	private int addIndex;// 添加下标

	private int removeIndex;// 删除下标

	private int count;// 数组当前数量(计数器)

	private Lock lock = new ReentrantLock();

	private Condition addThread = lock.newCondition();// 生产者的线程

	private Condition removeThread = lock.newCondition();// 消费者线程

	/**
	 * 初始化数组大小
	 *
	 * @param size
	 */
	public MyQueue(int length) {
		item = new Object[length];
	}

	/**
	 *   添加元素（add/offer/put）
	 * @param t
	 * @throws InterruptedException
	 */
	public void add(T t) throws InterruptedException {
		lock.lock();// 获得锁
		try {
			// 满了则一直等待
			while (item.length == count) {
				addThread.await();
			}
			// 否则将当前元素放入数组
			item[addIndex] = t;

			// 如果刚好满了,重新初始化
			if (++addIndex == item.length) {// addIndex自增操作和判断操作在一起
				addIndex = 0;
			}
			count++;
			removeThread.signal();

		} finally {
			lock.unlock();
		}
	}

	/**
	 *  删除一个元素(remove/pool/take)
	 *
	 * @param t
	 * @throws InterruptedException
	 */
	@SuppressWarnings("unchecked")
	public T remove() throws InterruptedException {
		lock.lock();
		try {
			while (count == 0) {
				removeThread.await();
			}

			Object o = item[removeIndex];
			// 取到最后一个元素,重新初始化
			if (++removeIndex == item.length) {
				removeIndex = 0;
			}
			count--;
			addThread.signal();

			return (T) o;
		} finally {
			lock.unlock();
		}
	}

}
